package cn.zhangfusheng.elasticsearch.jexl.analysis.impl;

import cn.zhangfusheng.elasticsearch.jexl.Jexl3Execute;
import cn.zhangfusheng.elasticsearch.jexl.Jexl3Util;
import cn.zhangfusheng.elasticsearch.jexl.analysis.Analysis;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 普通文本 表达式
 * @author fusheng.zhang
 * @date 2022-03-05 16:24:15
 */
@Data
public class ForAnalysis implements Analysis {

    /**
     * 循环变量名
     */
    private String variable;
    /**
     * for ()
     */
    private String forCondition;
    /**
     * for {}
     */
    private String forExecute;

    private List<Analysis> forAnalyses;

    @Override
    public String toString() {
        StringBuilder str = new StringBuilder();
        if (Objects.nonNull(forCondition)) {
            str.append("for ( ").append(variable).append(" in ").append(forCondition).append(" ){");
            if (Objects.nonNull(forExecute)) {
                str.append(forExecute);
            }
            if (Objects.nonNull(forAnalyses)) {
                forAnalyses.forEach(analysis -> str.append(analysis.toString()));
            }
            str.append("}");
        }
        return str.toString();
    }

    @Override
    public void execute(Jexl3Execute jexl3Execute) {
        Object oldValue = jexl3Execute.getParams().get(variable);
        Object execute = Jexl3Util.execute(jexl3Execute.getParams(), jexl3Execute.getConstantParams(), Jexl3Util.toStr(forCondition));
        Jexl3Util.asCollection(execute).stream()
                .peek(o -> jexl3Execute.setIndex(jexl3Execute.getIndex() + 1))
                .peek(o -> jexl3Execute.setParam("_index", jexl3Execute.getIndex()))
                .peek(o -> jexl3Execute.setParam(variable, o))
                .forEach(o -> {
                    if (StringUtils.isNotBlank(forExecute)) jexl3Execute.setStr(forCondition);
                    if (!CollectionUtils.isEmpty(forAnalyses)) {
                        forAnalyses.forEach(analysis -> analysis.execute(jexl3Execute));
                    }
                });
        jexl3Execute.setIndex(0);
        jexl3Execute.setParam(variable, oldValue);
    }
}
